import numpy as np 
 
a = np.array([1,2,3,4]) 
b = np.array([10,20,30,40]) 
c = a * b 
print (c)
print('='*32)
 
a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
b = np.array([0,1,2])
print(a + b)
print('='*32)
"""
这段代码演示了NumPy的广播机制，它允许不同形状的数组进行数学运算。下面我来详细解释计算逻辑：

## 数组形状分析
- 数组`a`是4×3的二维数组：`shape = (4, 3)`
- 数组`b`是一维数组：`shape = (3,)`

## 广播机制的执行过程

### 1. 形状对齐
NumPy首先比较两个数组的维度，将维度较少的数组`b`在前面补1，使其维度数与`a`相同：
- `a.shape = (4, 3)`保持不变
- `b.shape = (3,)` → 补1后变为`(1, 3)`

### 2. 维度扩展
接着，NumPy检查每个维度是否兼容。规则是：每个维度的大小要么相同，要么其中一个为1。

对于维度1：`a`是4，`b`是1 → 兼容（因为有一个为1）
对于维度2：`a`是3，`b`是3 → 兼容（大小相同）

### 3. 实际计算
广播机制会将数组`b`在第一个维度上复制4次，使其"变成"4×3的数组：
```
b广播后 = [[0, 1, 2],
          [0, 1, 2], 
          [0, 1, 2],
          [0, 1, 2]]
```

然后执行对应位置的加法运算：
```
a + b广播后 = [[0+0, 0+1, 0+2],
            [10+0, 10+1, 10+2],
            [20+0, 20+1, 20+2],
            [30+0, 30+1, 30+2]]
```
"""


a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]]) # (4,3)
b = np.array([1,2,3]) # (3,)->(1,3)
bb = np.tile(b, (4, 1))  # 重复 b 的各个维度
print(a + bb)
print('='*32)

"""
广播的规则:

让所有输入数组都向其中形状最长的数组看齐，形状中不足的部分都通过在前面加 1 补齐。
输出数组的形状是输入数组形状的各个维度上的最大值。
如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时，这个数组能够用来计算，否则出错。
当输入数组的某个维度的长度为 1 时，沿着此维度运算时都用此维度上的第一组值。
简单理解：对两个数组，分别比较他们的每一个维度（若其中一个数组没有当前维度则忽略），满足：

数组拥有相同形状。
当前维度的值相等。
当前维度的值有一个是 1。
若条件不满足，抛出 "ValueError: frames are not aligned" 异常。

"""